﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Starfire3d.Interfaces;

namespace Starfire3d.Data.Objects
{
    public class WeaponSystem : ShipSystem, IDataItem, ICloneable
    {
        #region Attributes
        /*
  [Hit:6 6 5 4 3 2]
  [Dmg:2 2 2 2 2 2]
  [RoF:1]
         */
        private List<int> toHit = new List<int>();
        private List<int> damage = new List<int>();
        private int rof;
        private int lastFired = -1;
        #endregion

        public WeaponSystem()
        {
        }

        #region Public Properties
        public bool CanBeIntercepted
        {
            get { return Data.GetBool("interceptable"); }
        }

        public int ROF
        {
            get { return rof; }
        }

        public bool InRange(int range)
        {
            if (range < 0 || range > toHit.Count - 1)
                return false;

            return true;
        }

        public int MaxRange()
        {
            return toHit.Count - 1;
        }

        public int MaxBestRange()
        {
            int bestHit = 0;
            int range = 0;
            int i = toHit.Count() - 1;

            while (i > 0)
            {
                if (toHit[i] > bestHit)
                {
                    bestHit = toHit[i];
                    range = i;
                }
                --i;
            }

            return range;
        }

        public int ToHit(int range, Unit entity)
        {
            if (range < 0 || range > toHit.Count - 1 || (!entity.Sheet.Details.HasSensors() && range > 10))
                return 0;

            return toHit[range];
        }

        public int Damage(int range)
        {
            if (range < 0 || range > toHit.Count - 1)
                return 0;

            return damage[range];
        }

        public int LastFired
        {
            get { return lastFired; }
            set { lastFired = value; }
        }
        #endregion

        #region Public Methods
        public int HitModifiers(Unit attacker, Unit target)
        {
            int modifiedHit = 0;

            if (Data.GetBool("LauncherBox"))
                modifiedHit -= 1;

            // PLASMAGUN : Ignore 1st 2 pts of EM/EMS.  Pg total all non-EM/EMS mods and / 2 (FRU).
            // PLASMATRP : Ignore 1st point of EM/EMS.

            if (Data.GetBool("PLASMATORPEDO"))
            {
                int bonus = (target.Sheet.Details.TurnMode / 3);

                if (target.Sheet.Details.TurnMode % 3 > 0)
                    bonus += 1;

                if (bonus > 3)
                    bonus = 3;
            }

            // HEM the bonus
            int hem = Math.Abs(modifiedHit);

            if (hem <= 2) {/*Do nothing*/ }
            else if (hem == 3) { hem = 2; }
            else if (hem <= 6) { hem = 3; }
            else if (hem >= 7) { hem = 4; }
            
            return modifiedHit < 0 ? -hem : hem;
        }

        public new bool BuildFromMetaData(MetaObject meta)
        {
            base.BuildFromMetaData(meta);

            foreach (string token in meta.TokenList)
            {
                string[] tokens = token.Split(':');

                // Single line Tags
                if (tokens.Count() == 1)
                    continue;

                if (tokens[0].ToLower() == "hit")
                {
                    string[] hit = tokens[1].Split(' ');
                    foreach (string v in hit)
                        toHit.Add(int.Parse(v));
                    continue;
                }
                if (tokens[0].ToLower() == "dmg")
                {
                    string[] dmg = tokens[1].Split(' ');
                    foreach (string v in dmg)
                        damage.Add(int.Parse(v));
                    continue;
                }
                if (tokens[0].ToLower() == "rof")
                {
                    rof = int.Parse(tokens[1]);
                    continue;
                }
            }

            return true;
        }

        public override string ToString()
        {
            return base.ToString();
        }
        #endregion

        #region ICloneable Members
        public new object Clone()
        {
            return this.MemberwiseClone();
        }
        #endregion
    }
}
